using SqlSugar;
using IM.Easy.Core.Services;
using IM.Easy.Core.Utils;
using IM.Easy.Infrastructure.Query;
using IM.Easy.Core.Extensions;
using IM.Easy.Entity.System;
using IM.Easy.SystemServices.Dtos;
using IM.Easy.SystemServices.IServices;
using IM.Easy.Core.OAuth.OAuthUser;

namespace IM.Easy.SystemServices.Services
{
    public class ExternalUserAccountService : AppServices<ExternalUserAccount>, IExternalUserAccountService
    {

        public ExternalUserAccountService(ISqlSugarClient db) : base(db)
        {

        }

        public ExternalUserAccount Create(ExternalUserAccount entity)
        {
            // TODO: 添加创建逻辑
            return Context.Insertable(entity).ExecuteReturnEntity();
        }

        public ExternalUserAccount GetById(long id)
        {
            // TODO: 添加获取逻辑
            return Context.Queryable<ExternalUserAccount>().InSingle(id);
        }

        public PageResponse<ExternalUserAccount> GetPageList(ExternalUserAccountQueryDto query)
        {
            var queryable = Context.Queryable<ExternalUserAccount>();
            var exp = Expressionable.Create<ExternalUserAccount>();
            exp = exp
                  .AndIF(!string.IsNullOrEmpty(query.UserName), s => s.UserName.Contains(query.UserName))
;
            var page = queryable
                 .Where(exp.ToExpression())
                 .ToPageList<ExternalUserAccount, ExternalUserAccount>(query);
            return page;
        }

        public bool Update(ExternalUserAccount entity)
        {
            // TODO: 添加更新逻辑
            return Context.Updateable(entity).ExecuteCommandHasChange();
        }

        public bool Delete(params long[] Id)
        {
            // TODO: 添加删除逻辑
            return Context.Deleteable<ExternalUserAccount>(Id).ExecuteCommandHasChange();
        }

        /// <summary>
        /// 获取本地账户
        /// </summary>
        /// <param name="provider"></param>
        /// <param name="openId"></param>
        /// <returns></returns>
        public SysUser GetLocalAccount(string provider, string openId)
        {
            var sysUser = Context.Queryable<SysUser>()
                       .InnerJoin<ExternalUserAccount>((su, eua) => eua.UserId == su.Id)
                       .Where((su, eua) => eua.Provider == provider && eua.ProviderUserId == openId)
                       .Single();
            return sysUser;
        }

        /// <summary>
        /// 通过提供商和开放ID获取用户信息
        /// </summary>
        /// <param name="provider"></param>
        /// <param name="openId"></param>
        /// <returns></returns>
        public ExternalUserAccount Get(string provider, string openId)
        {
            var user = GetFirst(s => s.Provider == provider && s.ProviderUserId == openId);
            return user;
        }

        /// <summary>
        /// 绑定当前账户
        /// </summary>
        /// <param name="user"></param>

        public ExternalUserAccount BindLocalAccount(SysUser user, ExternalUserAccount externalUser)
        {
            externalUser.UserId = user.Id;
            //Update(externalUser);
            base.InsertOrUpdate(externalUser);
            return externalUser;
        }

        /// <summary>
        /// 绑定校验
        /// </summary>
        /// <param name="externalUser"></param>
        /// <returns></returns>
        public bool BindValid(ExternalUserAccount externalUser)
        {
            var exist = IsAny(s => s.Provider == externalUser.Provider && s.ProviderUserId == externalUser.ProviderUserId && s.UserId != externalUser.UserId);
            if (exist) ExceptionUtils.ThrowBusinessException("绑定失败，已被其他账号绑定");
            return exist;
        }


        /// <summary>
        /// 解除绑定
        /// </summary>
        /// <param name="bindId"></param>
        public void Unbind(long bindId)
        {
            base.DeleteById(bindId);
        }
    }
}
